﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.Metadata;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace CPPEI.Coolzon.UI
{
    public delegate void PartSelectedEventHandler(UI.Part part);

    /// <summary>
    /// 数据组件
    /// </summary>
    public abstract partial class Part : UserControl, IPart, INotifyPropertyChanged
    {
        static Part()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Part), new FrameworkPropertyMetadata(typeof(Part)));
        }

        /// <summary>
        /// 组件第一次被激活,当调用过Active之后，此值将会变成false,默认是true
        /// </summary>
        protected bool IsFirstActive { get; private set; }

        /// <summary>
        /// 是否处于活动状态
        /// </summary>
        protected bool IsActived { get; private set; }

        /// <summary>
        /// 是否已经初始化完毕
        /// </summary>
        public bool IsInitiated { get; private set; }


        /// <summary>
        /// 是否已经销毁
        /// </summary>
        public bool IsDestroyed { get; private set; }

        /// <summary>
        /// 事件列表
        /// </summary>
        public List<Metadata.Event> EventList { get; set; }

        public object ToolbarContent
        {
            get
            {
                return GetValue(ToolbarContentProperty);
            }
            set
            {
                SetValue(ToolbarContentProperty, value);
            }
        }

        /// <summary>
        /// 参数列表
        /// </summary>
        public ParameterCollection Parameters { get; set; }

        /// <summary>
        /// 上一级组件
        /// </summary>
        public Part ParentPart { get; set; }

        private Part _selectPart;

        /// <summary>
        /// 配置元数据
        /// </summary>
        public Metadata.NodeBase Metadata { get; set; }

        /// <summary>
        /// 是否处于设计状态
        /// </summary>
        public bool XIsDesignMode
        {
            get
            {
                return (bool)GetValue(XIsDesignModeProperty);
            }
            set
            {
                SetValue(XIsDesignModeProperty, value);
            }
        }

        private StackPanel _toolbarPanel;

        /// <summary>
        /// 组件被选中的事件
        /// </summary>
        public event PartSelectedEventHandler PartSelected;

        /// <summary>
        /// 组件所运行的当前上下文信息
        /// </summary>
        public PartContext PartContext { get; private set; }

        /// <summary>
        /// [2017新增]
        /// 当前组件所在的场景
        /// </summary>
        public ScenePart Scene { get; set; }

        public Part()
        {
            Parameters = new ParameterCollection();

            IsFirstActive = true;
            IsActived = false;
            IsInitiated = false;
            IsDestroyed = false;

             _toolbarPanel = new StackPanel();
            _toolbarPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
            _toolbarPanel.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            this.ToolbarContent = _toolbarPanel;
            this.XLeft = 0;
            this.XTop = 0;

            XIsDesignMode = false;

            if(string.Equals(System.Configuration.ConfigurationManager.AppSettings["SysName"], "Designer"))
            {
                XBorderBrush = new BrushEx(new SolidColorBrush(Colors.Black));
                XBorderThickness = new Thickness(1);
            }
        }

        public void SetMetadata(Metadata.NodeBase metadata)
        {
            this.Metadata = metadata;
        }

        ///// <summary>
        ///// 获取脚本引擎
        ///// </summary>
        ///// <returns></returns>
        //public ScriptEngine GetScriptEngine()
        //{
        //    if (_scriptEngine == null)
        //    {
        //        _scriptEngine = new ScriptEngine();
        //    }

        //    if (_scriptEngine != null && _scriptEngine.IsUsable)
        //    {
        //        OnInitScriptEngine(_scriptEngine);
        //    }
        //    return _scriptEngine;
        //}

        ///// <summary>
        ///// 初始化脚本引擎
        ///// </summary>
        ///// <param name="engine"></param>
        //protected virtual void OnInitScriptEngine(ScriptEngine engine)
        //{
        //}

        /// <summary>
        /// 验证控件的可见度
        /// </summary>
        protected void ValidateDisplayCondition()
        {
            // 检查显示条件
            if (!string.IsNullOrEmpty(XDisplayCondition))
            {
                Logger.DebugToTag("UI", "控件{0}开始验证显示条件:{1}", this.Name, XDisplayCondition);
                ScriptEngine engine = PartContext.ScriptEngine;
                if (engine.IsUsable && engine.RunExpressionToBoolean(XDisplayCondition) == true)
                {
                    Logger.DebugToTag("UI", "控件{0}开始验证显示条件:{1}, 通过-显示组件", this.Name, XDisplayCondition);
                    Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    Logger.DebugToTag("UI", "控件{0}开始验证显示条件:{1}, 不通过-隐藏组件", this.Name, XDisplayCondition);
                    Visibility = System.Windows.Visibility.Hidden;
                }
            }
            else
            {
                Visibility = System.Windows.Visibility.Visible;
            }
        }
        
        /// <summary>
        /// 激活组建，将组建设置为激活状态
        /// </summary>
        public void Active(PartContext context)
        {
            PartContext = context;

            //#region 加载图片资源
            //// partFrame 没有metadata，目前是一个bug
            //if (this.Metadata != null)
            //{
            //    XPropertyUtility.LoadXProperty<ImageSource>(this);
            //    XPropertyUtility.LoadXProperty<ImageSource[]>(this);
            //}
            //#endregion

//#if DEBUG
//            Common.Logger.DebugToTag("UI", string.Format("part:{0} active", this.Name));
//#endif

            IsActived = true;

            try
            {
                OnActive(context);
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag("UI", "Part:{0} active exception{1}", this.Name, ex);
            }
            IsFirstActive = false;

            // 检查显示条件
            ValidateDisplayCondition();
        }

        /// <summary>
        /// 组建被激活事件，此方法需要子类来实现，在子类中根据需要做相应的处理
        /// </summary>
        protected virtual void OnActive(PartContext context)
        {
        }

        /// <summary>
        /// 组件不被激活
        /// </summary>
        public void Deactive()
        {
            if (this.PartContext != null)
            {
                OnDeactive(PartContext);
            }

            //#region 删除所有的图片资源
            //XPropertyUtility.UnloadXProperty<ImageSource>(this);
            //XPropertyUtility.UnloadXProperty<ImageSource[]>(this);
            //#endregion

            IsActived = false;
            //this.PartContext = null;

            //XPropertyUtility.ClearXProperties(this);
        }

        /// <summary>
        /// 组件从激活状态变成非激活状态时触发
        /// </summary>
        protected virtual void OnDeactive(PartContext context)
        {
        }

        /// <summary>
        /// 销毁组件
        /// </summary>
        public void Destory()
        {
            OnDestory();

            IsDestroyed = true;

            XPropertyUtility.ClearXProperties(this);
            this.PartContext = null;
            //Common.Logger.DebugToTag("Coolzon.UI", "销毁组件:{0}", this.Name);
        }

        protected virtual void OnDestory()
        {
        }

        /// <summary>
        /// 控件初始化事件
        /// </summary>
        public void Init(PartContext context)
        {
            PartContext = context;

            OnInit(context);
            ApplyXProperty();

            IsInitiated = true;
        }

        /// <summary>
        /// 组件被加载的事件，但是组件目前可能并没有显示在界面上
        /// </summary>
        protected virtual void OnInit(PartContext context)
        {
        }

        /// <summary>
        /// 冻结组建,此方法暂无作用
        /// </summary>
        public void Frozen()
        {
            OnFrozen();
        }

        public void Unfreeze()
        {
            OnUnfreeze();
        }

        protected virtual void OnFrozen()
        {
        }
        protected virtual void OnUnfreeze()
        {
        }

        /// <summary>
        /// 刷新，重新走一遍active的效果，只是动画
        /// </summary>
        public void Refresh()
        {
            if (IsInitiated && !IsDestroyed)
            {
                Logger.DebugToTag(Library.LogTAG, string.Format("组件:{0}执行刷新Refresh()", this.Name));
                ApplyXProperty();
                OnRefresh();
            }
        }

        protected virtual void OnRefresh()
        {
        }

        public void ApplyXProperty()
        {
            if (IsInitiated && !IsDestroyed)
            {
                Logger.DebugToTag(Library.LogTAG, string.Format("组件:{0}执行ApplyXProperty()", this.Name));
                OnApplyXProperty();
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(""));
                }
            }
        }

        protected virtual void OnApplyXProperty()
        {

        }

        /// <summary>
        /// 触发事件
        /// </summary>
        /// <param name="eventSource"></param>
        protected void RaiseEvent(string eventSource)
        {
        }

        /// <summary>
        /// 投影显示到图像上
        /// </summary>
        /// <returns></returns>
        [Obsolete("此方法还存在bug，无法正确的显示出activeX组件的内容")]
        public ImageSource ProjectionToImage()
        {
            this.Frozen();

            RenderTargetBitmap rtb = new RenderTargetBitmap((int)this.ActualWidth, (int)this.ActualHeight, 96, 96, PixelFormats.Default);
            rtb.Render(this);

            this.Unfreeze();

            return rtb;
        }

        /// <summary>
        /// 添加快捷按钮
        /// </summary>
        /// <param name="button"></param>
        public void AddToolbarButton(Button button)
        {
            this._toolbarPanel.Children.Add(button);
        }

        /// <summary>
        /// 迭代的寻找参数，直到找到最后一个节点
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public Metadata.Parameter GetParameter(string name)
        {
            Metadata.Parameter parameter = null;
            Part curPart = this;

            while (parameter == null && curPart != null)
            {
                parameter = curPart.Parameters.Get(name);
                curPart = curPart.ParentPart;
            }

            return parameter;
        }

        //protected override void OnMouseDown(MouseButtonEventArgs e)
        //{
        //    System.Diagnostics.Debug.WriteLine("mouse down on part:" + this.Name);
        //    this.Select();
        //    e.Handled = true;
        //    base.OnMouseDown(e);
        //}

        /// <summary>
        /// 获取距离左边的距离，算上父节点的距离
        /// </summary>
        /// <returns></returns>
        public double GetXOffsetLeft()
        {
            if (this.ParentPart == null)
            {
                return XLeft;
            }
            else
            {
                return XLeft + this.ParentPart.GetXOffsetLeft();
            }
        }

        /// <summary>
        /// 获取距离顶部的距离，算上父节点的距离
        /// </summary>
        /// <returns></returns>
        public double GetXOffsetTop()
        {
            if (ParentPart != null)
            {
                double top = XTop;

                UI.Part pPart = ParentPart;
                while (pPart.ParentPart != null)
                {
                    top += pPart.XTop;
                    pPart = pPart.ParentPart;
                }
                return top;
            }
            else
            {
                return XTop;
            }
        }

        public void SetXOffsetLeft(double left)
        {
            double relativeLeft = left;
            UI.Part pPart = ParentPart;
            while (pPart != null)
            {
                relativeLeft -= pPart.XLeft;
                pPart = pPart.ParentPart;
            }
            this.XLeft = relativeLeft;
        }

        public void SetXOffsetTop(double top)
        {
            UI.Part pPart = ParentPart;
            while (pPart != null)
            {
                top -= pPart.XTop;
                pPart = pPart.ParentPart;
            }
            this.XTop = top;
        }

        public void Select()
        {
            if (_selectPart != null)
            {
                if (ParentPart != null)
                {
                    ParentPart.OnChildPartSelected(_selectPart);
                }
                else
                {
                    if (PartSelected != null)
                    {
                        PartSelected(_selectPart );
                    }
                }
            }
            else
            {
                if (ParentPart != null)
                {
                    ParentPart.OnChildPartSelected(this);
                }
                else
                {
                    if (PartSelected != null)
                    {
                        PartSelected(this);
                    }
                }
            }
        }

        private void OnChildPartSelected(UI.Part childPart)
        {
            if (ParentPart != null)
            {
                ParentPart.OnChildPartSelected(childPart);
            }
            else
            {
                if (PartSelected != null)
                {
                    PartSelected(childPart);
                }
            }
        }

        protected void UpdateSize()
        {
            if (ParentPart != null)
            {
                ParentPart.OnChildPartUpdateSize(this);
            }
        }

        private void OnChildPartUpdateSize(UI.Part childPart)
        {
            Canvas.SetLeft(childPart, childPart.XLeft);
            Canvas.SetTop(childPart, childPart.XTop);
        }

        /// <summary>
        /// 获取包含此点的组件实例
        /// </summary>
        /// <param name="type"></param>
        /// <param name="pointInRoot"></param>
        /// <param name="rootElement"></param>
        /// <returns></returns>
        [Obsolete("此方法应该迁移到IPartContainer中")]
        public virtual Part GetPartAtPoint(Type type, Point pointInRoot, UIElement rootElement)
        {
            if (!XIsVisible)
            {
                return null;
            }

            if (this.GetType() == type || this.GetType().IsSubclassOf(type)
                || type.IsAssignableFrom(this.GetType()))
            {
                Point absolutePoint = this.TranslatePoint(new Point(0, 0), rootElement);
                if (absolutePoint.X <= pointInRoot.X && absolutePoint.Y <= pointInRoot.Y
                    && absolutePoint.X + this.XWidth >= pointInRoot.X
                    && absolutePoint.Y + this.XHeight >= pointInRoot.Y)
                {
                    return this;
                }
            }
            return null;
        }

        #region method v1.5
        /// <summary>
        /// 获取组件的绝对位置，相对于场景
        /// </summary>
        /// <returns></returns>
        public Point XGetAbsolutePos()
        {
            var parentPart = this.XGetParent();
            if (parentPart != null)
            {
                Point posOfParent = parentPart.XGetAbsolutePos();
                if (parentPart is IPartContainer)
                {
                    var parentContainer = parentPart as IPartContainer;
                    Point offsetOfContent = parentContainer.XGetContentPos();
                    return new Point(this.XLeft + offsetOfContent.X + posOfParent.X,
                        this.XTop + offsetOfContent.Y + posOfParent.Y);
                }
                else
                {
                    return new Point(this.XLeft + posOfParent.X, this.XTop + posOfParent.Y);
                }
            }
            return new Point(this.XLeft, this.XTop);
        }

        /// <summary>
        /// 获取组件的位置，相对于父容器
        /// </summary>
        /// <returns></returns>
        public Point XGetPos()
        {
            return new Point(this.XLeft, this.XTop);
        }

        /// <summary>
        /// 获取组件的大小
        /// </summary>
        /// <returns></returns>
        public Size XGetSize()
        {
            return new Size(this.XWidth, this.XHeight);
        }

        /// <summary>
        /// 测试是否x，y点是否命中了组件实例
        /// </summary>
        /// <param name="pointInScene">场景中的坐标点</param>
        /// <returns></returns>
        public virtual Data.XHitResult XHitTest(Point pointInScene)
        {
            if (!XIsVisible)
            {
                return new Data.XHitResult(false, null, default(Point));
            }

            Point pos = this.XGetAbsolutePos();
            Size size = this.XGetSize();

            if(pointInScene.X >= pos.X
                && pointInScene.Y >= pos.Y
                && pointInScene.X <= pos.X + size.Width
                && pointInScene.Y <= pos.Y + size.Height)
            {
                return new Data.XHitResult(true, this, new Point(pointInScene.X - pos.X, pointInScene.Y - pos.Y));
            }
            return new Data.XHitResult(false, null, default(Point));
        }

        /// <summary>
        /// 测试是否x，y点是否命中了组件实例
        /// </summary>
        /// <typeparam name="T">命中的组件必须属于这个类型</typeparam>
        /// <param name="pointInScene">场景中的坐标点</param>
        /// <returns></returns>
        public virtual Data.XHitResult XHitTest<T>(Point pointInScene)
        {
            if (!XIsVisible)
            {
                return new Data.XHitResult(false, null, default(Point));
            }

            Type type = typeof(T);
            Point pos = this.XGetAbsolutePos();
            Size size = this.XGetSize();

            if (pointInScene.X >= pos.X
                && pointInScene.Y >= pos.Y
                && pointInScene.X <= pos.X + size.Width
                && pointInScene.Y <= pos.Y + size.Height)
            {
                if (this.GetType() == type || this.GetType().IsSubclassOf(type)
                    || type.IsAssignableFrom(this.GetType()))
                {
                    return new Data.XHitResult(true, this, new Point(pointInScene.X - pos.X, pointInScene.Y - pos.Y));
                }
            }
            return new Data.XHitResult(false, null, default(Point));
        }

        /// <summary>
        /// 获取组件的父组件对象
        /// </summary>
        /// <returns></returns>
        public Part XGetParent()
        {
            return ParentPart;
        }

        /// <summary>
        /// 配置源数据对象
        /// </summary>
        /// <returns></returns>
        public Metadata.NodeBase XGetMetadata()
        {
            return this.Metadata;
        }
        #endregion

        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 通知属性有变化
        /// </summary>
        /// <param name="propertyName"></param>
        protected void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// 视图的左上角坐标（相对于屏幕）
        /// 视图的右下角坐标（相对于屏幕）
        /// </summary>
        /// <param name="ltPtOfView"></param>
        /// <param name="rbPtOfView"></param>
        public virtual void VisibleRegionChange(Point ltPtOfView, Point rbPtOfView)
        {
            Point ltPtOfPart = this.PointToScreen(new Point(0, 0));
            Point rbPtOfPart = this.PointToScreen(new Point(this.ActualWidth, this.ActualHeight));

            Point ltPtOfActual = new Point(0, 0);
            Point rbPtOfActual = new Point(0, 0);

            double left = 0;
            double top = 0;
            double width = 0;
            double height = 0;

            if (rbPtOfPart.X <= ltPtOfView.X
                || rbPtOfPart.Y <= ltPtOfView.Y
                ||  ltPtOfPart.X >= rbPtOfView.X
                || ltPtOfPart.Y >= rbPtOfView.Y)
            {
                // 超出了范围
                width = 0;
                height = 0;
            }
            else if (ltPtOfPart.X <= ltPtOfView.X
                || ltPtOfPart.Y <= ltPtOfView.Y
                || rbPtOfPart.X >= rbPtOfView.X
                || rbPtOfPart.Y >= rbPtOfView.Y)
            {
                // 在内部或者相交
                ltPtOfActual.X = GetGreater(ltPtOfPart.X, ltPtOfView.X);
                ltPtOfActual.Y = GetGreater(ltPtOfPart.Y, ltPtOfView.Y);
                rbPtOfActual.X = GetLesser(rbPtOfPart.X, rbPtOfView.X);
                rbPtOfActual.Y = GetLesser(rbPtOfPart.Y, rbPtOfView.Y);

                left = ltPtOfActual.X - ltPtOfPart.X;
                top = ltPtOfActual.Y - ltPtOfPart.Y;
                width = rbPtOfActual.X - ltPtOfActual.X;
                height = rbPtOfActual.Y - ltPtOfActual.Y;
            }


            OnVisibleRegionChanged(new Rect(left, top, width, height));
        }

        private double GetGreater(double x1, double x2)
        {
            if (x1 > x2)
            {
                return x1;
            }
            return x2;
        }
        private double GetLesser(double x1, double x2)
        {
            if (x1 < x2)
            {
                return x1;
            }
            return x2;
        }

        /// <summary>
        /// 组件可也看见的区域变动事件
        /// </summary>
        /// <param name="region"></param>
        protected virtual void OnVisibleRegionChanged(System.Windows.Rect region)
        {
        }

        protected void InjectionParameters(EventContext context, ActionUrl url)
        {
            // 更细参数的值
            foreach (string key in url.ParameterString.Keys)
            {
                if (context.Arguments.ContainsKey(key))
                {
                    continue;
                }
                string pValue = url.ParameterString[key];
                context.Arguments.Add(key, ParseValueString(pValue));
            }
        }

        /// <summary>
        /// 触发鼠标点击事件
        /// </summary>
        /// <param name="eventType"></param>
        /// <param name="point"></param>
        public void OnMouseEvent(MouseEventType eventType, Point point)
        {
            return;
            /*
            if (this.EventList != null)
            {
                Common.Logger.DebugToTag("UI", "Part OnMouseEvent event:{0} point:{1},{2}", eventType.Name, point.X, point.Y);
                // 扫描组件的所有事件配置
                ScriptEngine script = ScriptEngine.Instance;
                script.AddCode("var args={mouse:{x:" + point.X.ToString() + ", y:" + point.Y.ToString() + "}};");
                for (int index = 0; index < this.EventList.Count; index++)
                {
                    Metadata.Event @event = this.EventList[index];
                    // 检查事件类型
                    if (@event.Source.ToUpper() == eventType.Name.ToUpper())
                    {
                        // 检查事件条件
                        if (string.IsNullOrEmpty(@event.Condition)
                            || (bool)script.RunExpression(@event.Condition))
                        {
                            // 往事件总线中发送数据交互事件
                            ActionUrl url = new ActionUrl(@event.Action);
                            EventContext context = new EventContext();
                            context.ActionType = url.ActionType;
                            context.TargetFrameName = url.TargetFrame;
                            context.TargetSceneName = url.TargetScene;

                            this.InjectionParameters(context, url);

                            // 向事件总线发送组件事件响应事件
                            Common.EventBus.Instance.Publish(context);
                        }
                    }
                }
            }*/
        }

        /// <summary>
        /// 解析值得定义文字，返回具体的值
        /// </summary>
        /// <param name="valueString"></param>
        /// <returns></returns>
        protected string ParseValueString(string valueString)
        {
            if(string.IsNullOrEmpty(valueString))
            {
                return valueString;
            }
            else if (valueString.StartsWith("@"))
            {
                // 参数的值引用配置中的参数的值
                string parameterName = valueString.Substring(1, valueString.Length - 1);

                Metadata.Parameter parameter = this.GetParameter(parameterName);
                if (parameter != null)
                {
                    return parameter.Value;
                }
                else
                {
                    return string.Empty;
                }
            }
            //window.开头的或'开头的按脚本执行，否则直接返回
            else if(valueString.StartsWith("window.") || valueString.StartsWith("'"))
            {
                object valueObj = PartContext.ScriptEngine.RunExpression(valueString);
                if (valueObj != null)
                {
                    return valueObj.ToString();
                }
                return valueString;
            }
            else
            {
                return valueString;
            }
        }

        /// <summary>
        /// 保存图像
        /// </summary>
        /// <returns></returns>
        [Obsolete("请使用ProjectionToImage方法")]
        public ImageSource Print()
        {
            RenderTargetBitmap rtb = new RenderTargetBitmap((int)this.ActualWidth, (int)this.ActualHeight, 96, 96, PixelFormats.Default);
            rtb.Render(this);
            return rtb;
        }

        /// <summary>
        /// 获得组件所在容器框架的名称
        /// </summary>
        /// <param name="part"></param>
        /// <returns></returns>
        public static string GetDefaultContainerFrameName(UI.Part part)
        {
            return string.Format("_{0}_Frame", part.Name);
        }

        /// <summary>
        /// 获得组件所在容器框架的名称
        /// </summary>
        /// <param name="partName"></param>
        /// <returns></returns>
        public static string GetDefaultContainerFrameName(string partName)
        {
            return string.Format("_{0}_Frame", partName);
        }

        /// <summary>
        /// 重置组件的状态
        /// </summary>
        public void Reset()
        {
            OnReset();
        }

        /// <summary>
        /// 重置组件的状态
        /// </summary>
        protected virtual void OnReset()
        {
        }

        /// <summary>
        /// 设置组件的属性值
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        public void SetPropertyXmlString(string propertyName, object value)
        {
            XProperty.XPropertyDescription description = XPropertyUtility.GetXPropertyDescription(this, propertyName);
            if (description != null)
            {
                XProperty.Converters.ConvertContext context = new XProperty.Converters.ConvertContext();
                Coolzon.Metadata.ValueNode valueNode = Coolzon.Metadata.ValueNode.Parse(Convert.ToString(value));
                XPropertyUtility.SetXPropertyValue(context, this, description, valueNode);
            }
        }

        #region ViewState
        ///// <summary>
        ///// 加载组件的viewstate
        ///// </summary>
        ///// <param name="partState"></param>
        //public void LoadViewState(PartViewState partState)
        //{
        //    OnLoadViewState(partState);
        //}

        ///// <summary>
        ///// 加载组件的viewstate
        ///// </summary>
        ///// <param name="partState"></param>
        //protected virtual void OnLoadViewState(PartViewState partState)
        //{
        //}

        ///// <summary>
        ///// 保存ViewState
        ///// </summary>
        ///// <param name="partState"></param>
        //public void SaveViewState(out PartViewState partState)
        //{
        //    this.OnSaveViewState(out partState);
        //}

        ///// <summary>
        ///// 保存ViewState
        ///// </summary>
        ///// <param name="partState"></param>
        //protected virtual void OnSaveViewState(out PartViewState partState)
        //{
        //    partState = null;
        //}

        public virtual void LoadViewState(Coolzon.ViewState.ViewState viewState)
        {
        }

        public virtual void SaveViewState(Coolzon.ViewState.ViewState viewState)
        {
        }

        #endregion

        /// <summary>
        /// 回溯父节点是否都可见，当设置区域不可见的时候，区域里的组件是可见的，所以需要回溯去寻找。
        /// </summary>
        /// <returns></returns>
        public bool IsVisibleAndParentVisible()
        {
            if (!XIsVisible)
            {
                return false;
            }
            if (ParentPart != null)
            {
                return ParentPart.IsVisibleAndParentVisible();
            }
            return XIsVisible;
        }

        public override string ToString()
        {
            return string.Format("{0}:{1}", GetType().Name, this.Name);
        }

        public virtual void RaiseScriptNetEvent(string eventName, string dataString)
        {
        }
    }
}
